home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 1 / Meeting Pearls Vol 1 (1994).iso / installed_progs / text / faqs / objective-c.sample < prev    next >
Encoding:
Internet Message Format  |  1994-04-18  |  23.1 KB

  1. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  2. Newsgroups: comp.lang.objective-c,comp.answers,news.answers
  3. From: tiggr@es.ele.tue.nl (Tiggr)
  4. Date: 17 Apr 1994 16:04:32 GMT
  5.  
  6. Archive-name: Objective-C/sample
  7. Version: $Id: sample.preamble,v 2.3 1994/01/28 13:27:07 tiggr Exp $
  8.  
  9.  
  10.         A simple sample
  11.         Objective-C program
  12.  
  13.  
  14. This is the third part in a series of three informational postings
  15. concerning comp.lang.objective-c.  This article presents a simple program
  16. written in Objective-C.  The program consist of several files which are
  17. contained in a shar file (see instructions below on how to unpack).  [Note,
  18. from version 2.3 of this file, the sample has been changed in order to
  19. reduce the number of compiler warnings (down to 1, which is in there for
  20. explanatory purposes) and to reflect the use of `+alloc' and `-init' instead
  21. of `+new'.]
  22.  
  23. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  24. many people.  The current version is being maintained by Tiggr, aided by a
  25. lot of people, including Paul Sanchez and Bill Shirley.
  26.  
  27. Send your suggestions, additions, bug reports, comments and fixes to
  28. `tiggr@es.ele.tue.nl'.
  29.  
  30.  
  31. #---------------------------------- cut here ----------------------------------
  32. # This is a shell archive.  Remove anything before this line,
  33. # then unpack it by saving it in a file and typing "sh file".
  34. #
  35. # Wrapped by Pieter Schoenmakers <tiggr@viper> on Fri Apr 15 21:26:28 1994
  36. #
  37. # This archive contains:
  38. #    objc-sample    
  39. #
  40. # Existing files will not be overwritten.
  41. # Error checking via wc(1) will be performed.
  42.  
  43. LANG=""; export LANG
  44. PATH=/bin:/usr/bin:$PATH; export PATH
  45.  
  46. echo mkdir - objc-sample
  47. mkdir objc-sample
  48.  
  49. if test -f objc-sample/README
  50. then
  51.     echo Ok to overwrite existing file objc-sample/README\?
  52.     read answer
  53.     case "$answer" in
  54.     [yY]*)    echo Proceeding;;
  55.     *)    echo Aborting; exit 1;;
  56.     esac
  57.     rm -f objc-sample/README
  58.     if test -f objc-sample/README
  59.     then
  60.         echo Error: could not remove objc-sample/README, aborting
  61.         exit 1
  62.     fi
  63. fi
  64. echo x - objc-sample/README
  65. cat >objc-sample/README <<'@EOF'
  66. This directory contains the complete code for the "Simple Sample Objective-C
  67. program" described in the comp.lang.objective-c FAQ.  If you have a suitable
  68. compiler, use the supplied Makefile.  Otherwise, program output can be found
  69. in the file "output".
  70.  
  71. You should probably read "main.m" first.  It is very heavily annotated.
  72.  
  73. Also note and read the file COPYRIGHT.
  74. @EOF
  75. set `wc -lwc <objc-sample/README`
  76. if test $1$2$3 != 855366
  77. then
  78.     echo ERROR: wc results of objc-sample/README are $* should be 8 55 366
  79. fi
  80.  
  81. chmod 644 objc-sample/README
  82.  
  83. if test -f objc-sample/Char.h
  84. then
  85.     echo Ok to overwrite existing file objc-sample/Char.h\?
  86.     read answer
  87.     case "$answer" in
  88.     [yY]*)    echo Proceeding;;
  89.     *)    echo Aborting; exit 1;;
  90.     esac
  91.     rm -f objc-sample/Char.h
  92.     if test -f objc-sample/Char.h
  93.     then
  94.         echo Error: could not remove objc-sample/Char.h, aborting
  95.         exit 1
  96.     fi
  97. fi
  98. echo x - objc-sample/Char.h
  99. cat >objc-sample/Char.h <<'@EOF'
  100. #import <objc/Object.h>
  101.  
  102. @interface Char: Object
  103. {
  104.   int value;
  105. }
  106.  
  107. -init: (int) x;
  108. -report;
  109.  
  110. @end
  111. @EOF
  112. set `wc -lwc <objc-sample/Char.h`
  113. if test $1$2$3 != 111498
  114. then
  115.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 14 98
  116. fi
  117.  
  118. chmod 644 objc-sample/Char.h
  119.  
  120. if test -f objc-sample/Node.h
  121. then
  122.     echo Ok to overwrite existing file objc-sample/Node.h\?
  123.     read answer
  124.     case "$answer" in
  125.     [yY]*)    echo Proceeding;;
  126.     *)    echo Aborting; exit 1;;
  127.     esac
  128.     rm -f objc-sample/Node.h
  129.     if test -f objc-sample/Node.h
  130.     then
  131.         echo Error: could not remove objc-sample/Node.h, aborting
  132.         exit 1
  133.     fi
  134. fi
  135. echo x - objc-sample/Node.h
  136. cat >objc-sample/Node.h <<'@EOF'
  137. #import <objc/Object.h>
  138.  
  139. @interface Node : Object
  140. {
  141.   id next;
  142.   id data;
  143. }
  144.  
  145. -init: anItem;        // create a Node and store anItem in it
  146. -free;            // free a Node and return the item in it
  147. -next;            // report the id of the next node after this one
  148. -setNext: aNode;    // make the next node be aNode
  149.  
  150. @end
  151. @EOF
  152. set `wc -lwc <objc-sample/Node.h`
  153. if test $1$2$3 != 1456295
  154. then
  155.     echo ERROR: wc results of objc-sample/Node.h are $* should be 14 56 295
  156. fi
  157.  
  158. chmod 644 objc-sample/Node.h
  159.  
  160. if test -f objc-sample/Node.m
  161. then
  162.     echo Ok to overwrite existing file objc-sample/Node.m\?
  163.     read answer
  164.     case "$answer" in
  165.     [yY]*)    echo Proceeding;;
  166.     *)    echo Aborting; exit 1;;
  167.     esac
  168.     rm -f objc-sample/Node.m
  169.     if test -f objc-sample/Node.m
  170.     then
  171.         echo Error: could not remove objc-sample/Node.m, aborting
  172.         exit 1
  173.     fi
  174. fi
  175. echo x - objc-sample/Node.m
  176. cat >objc-sample/Node.m <<'@EOF'
  177. #import <objc/Object.h>
  178. #import "Node.h"
  179.  
  180. @implementation    Node: Object
  181.  
  182. -init: anItem
  183. {
  184.   self = [super init];
  185.   next = 0;
  186.   data = anItem;
  187.   return self;
  188. }
  189.  
  190. -free
  191. {
  192.   id tmp = data;
  193.   [super free];
  194.   return tmp;
  195. }
  196.  
  197. -next
  198. {
  199.   return next;
  200. }
  201.  
  202. -setNext: aNode
  203. {
  204.   next = aNode;
  205.   return self;
  206. }
  207.  
  208. @end
  209. @EOF
  210. set `wc -lwc <objc-sample/Node.m`
  211. if test $1$2$3 != 3249299
  212. then
  213.     echo ERROR: wc results of objc-sample/Node.m are $* should be 32 49 299
  214. fi
  215.  
  216. chmod 644 objc-sample/Node.m
  217.  
  218. if test -f objc-sample/Queue.h
  219. then
  220.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  221.     read answer
  222.     case "$answer" in
  223.     [yY]*)    echo Proceeding;;
  224.     *)    echo Aborting; exit 1;;
  225.     esac
  226.     rm -f objc-sample/Queue.h
  227.     if test -f objc-sample/Queue.h
  228.     then
  229.         echo Error: could not remove objc-sample/Queue.h, aborting
  230.         exit 1
  231.     fi
  232. fi
  233. echo x - objc-sample/Queue.h
  234. cat >objc-sample/Queue.h <<'@EOF'
  235. #import <objc/Object.h>
  236. #import "Node.h"
  237.  
  238. @interface Queue: Object
  239. {
  240.   id head;
  241.   id tail;
  242.   unsigned qsize;
  243. }
  244.  
  245. -empty;            // clear out all contents of the Queue
  246. -put: anItem;        // put anItem on the Queue
  247. -get;            // return the item on top of the Queue
  248. -(unsigned int) size;    // tell us the current size of the Queue
  249.  
  250. @end
  251. @EOF
  252. set `wc -lwc <objc-sample/Queue.h`
  253. if test $1$2$3 != 1655319
  254. then
  255.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 16 55 319
  256. fi
  257.  
  258. chmod 644 objc-sample/Queue.h
  259.  
  260. if test -f objc-sample/Queue.m
  261. then
  262.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  263.     read answer
  264.     case "$answer" in
  265.     [yY]*)    echo Proceeding;;
  266.     *)    echo Aborting; exit 1;;
  267.     esac
  268.     rm -f objc-sample/Queue.m
  269.     if test -f objc-sample/Queue.m
  270.     then
  271.         echo Error: could not remove objc-sample/Queue.m, aborting
  272.         exit 1
  273.     fi
  274. fi
  275. echo x - objc-sample/Queue.m
  276. cat >objc-sample/Queue.m <<'@EOF'
  277. #import "Queue.h"
  278.  
  279. @implementation    Queue
  280.  
  281. -empty
  282. {
  283.   while([self size])
  284.     [[self get] free];
  285.   return self;
  286. }
  287.  
  288. -put: anItem
  289. {
  290.   if (tail)
  291.     tail = [[tail setNext : [[Node alloc] init: anItem]] next];
  292.   else
  293.     head = tail = [[Node alloc] init: anItem];
  294.   ++qsize;
  295.   return self;
  296. }
  297.  
  298. -get
  299. {
  300.   id contents;
  301.   id old_head = head;
  302.  
  303.   head = [head next];
  304.   contents = [old_head free];
  305.   if (--qsize == 0)
  306.     tail = head;
  307.   return contents;
  308. }
  309.  
  310. -(unsigned) size
  311. {
  312.   return qsize;
  313. }
  314.  
  315. @end
  316. @EOF
  317. set `wc -lwc <objc-sample/Queue.m`
  318. if test $1$2$3 != 3975486
  319. then
  320.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 39 75 486
  321. fi
  322.  
  323. chmod 644 objc-sample/Queue.m
  324.  
  325. if test -f objc-sample/Stack.h
  326. then
  327.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  328.     read answer
  329.     case "$answer" in
  330.     [yY]*)    echo Proceeding;;
  331.     *)    echo Aborting; exit 1;;
  332.     esac
  333.     rm -f objc-sample/Stack.h
  334.     if test -f objc-sample/Stack.h
  335.     then
  336.         echo Error: could not remove objc-sample/Stack.h, aborting
  337.         exit 1
  338.     fi
  339. fi
  340. echo x - objc-sample/Stack.h
  341. cat >objc-sample/Stack.h <<'@EOF'
  342. #import <objc/Object.h>
  343. #import "Node.h"
  344.  
  345. @interface Stack: Object
  346. {
  347.   id stack;
  348.   unsigned int stack_size;
  349. }
  350.  
  351. -empty;                // clear out all contents of the Stack
  352. -put: anItem;            // put anItem on the Stack
  353. -get;                // return the item on top of the Stack
  354. -(unsigned) size;        // tell us the current size of the Stack
  355.  
  356. @end
  357. @EOF
  358. set `wc -lwc <objc-sample/Stack.h`
  359. if test $1$2$3 != 1553318
  360. then
  361.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 15 53 318
  362. fi
  363.  
  364. chmod 644 objc-sample/Stack.h
  365.  
  366. if test -f objc-sample/Stack.m
  367. then
  368.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  369.     read answer
  370.     case "$answer" in
  371.     [yY]*)    echo Proceeding;;
  372.     *)    echo Aborting; exit 1;;
  373.     esac
  374.     rm -f objc-sample/Stack.m
  375.     if test -f objc-sample/Stack.m
  376.     then
  377.         echo Error: could not remove objc-sample/Stack.m, aborting
  378.         exit 1
  379.     fi
  380. fi
  381. echo x - objc-sample/Stack.m
  382. cat >objc-sample/Stack.m <<'@EOF'
  383. #import "Stack.h"
  384.  
  385. @implementation    Stack
  386.  
  387. -empty
  388. {
  389.   while([self size])
  390.     [[self get] free];
  391.   return self;
  392. }
  393.  
  394. -put: anItem
  395. {
  396.   stack = [[[Node alloc] init: anItem] setNext : stack];
  397.   ++stack_size;
  398.   return self;
  399. }
  400.  
  401. -get
  402. {
  403.   id contents;
  404.   id old_stack = stack;
  405.  
  406.   stack = [stack next];
  407.   contents = [old_stack free];
  408.   --stack_size;
  409.   return contents;
  410. }
  411.  
  412. -(unsigned) size
  413. {
  414.   return stack_size;
  415. }
  416.  
  417. @end
  418. @EOF
  419. set `wc -lwc <objc-sample/Stack.m`
  420. if test $1$2$3 != 3557407
  421. then
  422.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 35 57 407
  423. fi
  424.  
  425. chmod 644 objc-sample/Stack.m
  426.  
  427. if test -f objc-sample/output
  428. then
  429.     echo Ok to overwrite existing file objc-sample/output\?
  430.     read answer
  431.     case "$answer" in
  432.     [yY]*)    echo Proceeding;;
  433.     *)    echo Aborting; exit 1;;
  434.     esac
  435.     rm -f objc-sample/output
  436.     if test -f objc-sample/output
  437.     then
  438.         echo Error: could not remove objc-sample/output, aborting
  439.         exit 1
  440.     fi
  441. fi
  442. echo x - objc-sample/output
  443. cat >objc-sample/output <<'@EOF'
  444. Output from demo, excluding Char class:
  445.  
  446. Include the Char class in the demo? (y/n): n
  447. queue:   5, stack:-5.0
  448. queue: 4.0, stack:  -4
  449. queue:   3, stack:-3.0
  450. queue: 2.0, stack:  -2
  451. queue:   1, stack:-1.0
  452. queue: 0.0, stack:   0
  453. queue:  -1, stack: 1.0
  454. queue:-2.0, stack:   2
  455. queue:  -3, stack: 3.0
  456. queue:-4.0, stack:   4
  457. queue:  -5, stack: 5.0
  458.  
  459. Output from demo, including Char class:
  460.  
  461. Include the Char class in the demo? (y/n): y
  462. queue:   5, stack:   h
  463. queue:   q, stack:-4.0
  464. queue:   3, stack:   j
  465. queue:   o, stack:-2.0
  466. queue:   1, stack:   l
  467. queue:   m, stack: 0.0
  468. queue:  -1, stack:   n
  469. queue:   k, stack: 2.0
  470. queue:  -3, stack:   p
  471. queue:   i, stack: 4.0
  472. queue:  -5, stack:   r
  473. @EOF
  474. set `wc -lwc <objc-sample/output`
  475. if test $1$2$3 != 29111679
  476. then
  477.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  478. fi
  479.  
  480. chmod 644 objc-sample/output
  481.  
  482. if test -f objc-sample/Char.m
  483. then
  484.     echo Ok to overwrite existing file objc-sample/Char.m\?
  485.     read answer
  486.     case "$answer" in
  487.     [yY]*)    echo Proceeding;;
  488.     *)    echo Aborting; exit 1;;
  489.     esac
  490.     rm -f objc-sample/Char.m
  491.     if test -f objc-sample/Char.m
  492.     then
  493.         echo Error: could not remove objc-sample/Char.m, aborting
  494.         exit 1
  495.     fi
  496. fi
  497. echo x - objc-sample/Char.m
  498. cat >objc-sample/Char.m <<'@EOF'
  499. #import <stdio.h>
  500. #import "Char.h"
  501.  
  502. @implementation Char
  503. {
  504.   int value;
  505. }
  506.  
  507. - init: (int) x
  508. {
  509.   [super init];        // In case the parent class is doing
  510.               // something special in its init...
  511.   value = x;
  512.   return self;
  513. }
  514.  
  515. - report
  516. {
  517.   printf("   %c", value);
  518.   return self;
  519. }
  520.  
  521. @end
  522. @EOF
  523. set `wc -lwc <objc-sample/Char.m`
  524. if test $1$2$3 != 2347279
  525. then
  526.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  527. fi
  528.  
  529. chmod 644 objc-sample/Char.m
  530.  
  531. if test -f objc-sample/main.m
  532. then
  533.     echo Ok to overwrite existing file objc-sample/main.m\?
  534.     read answer
  535.     case "$answer" in
  536.     [yY]*)    echo Proceeding;;
  537.     *)    echo Aborting; exit 1;;
  538.     esac
  539.     rm -f objc-sample/main.m
  540.     if test -f objc-sample/main.m
  541.     then
  542.         echo Error: could not remove objc-sample/main.m, aborting
  543.         exit 1
  544.     fi
  545. fi
  546. echo x - objc-sample/main.m
  547. cat >objc-sample/main.m <<'@EOF'
  548. /* main.m - comp.lang.objective-c simple sample Objective-C program.  */
  549.  
  550. // This is a comment, just like the previous line.  Everything to the right
  551. // of a double slash is ignored.
  552.  
  553. /* Classes are the one real extension which Objective-C adds to C.  A class
  554.    is a description of a collection of data, like a C structure, and the
  555.    methods by which that data may be accessed or manipulated.  Instances of
  556.    a class are called objects, and methods are invoked by sending messages
  557.    to either the class itself, to produce objects, or to those objects.  The
  558.    recipient of a message is called a "receiver".  The form of a message is:
  559.  
  560.     [receiver method andMaybeSomeArguments]
  561.  
  562.    the receiver and method components are mandatory, as are the square
  563.    brackets surrounding the message.  Additional arguments may or may not be
  564.    present, depending upon the method definition.  Messages may appear
  565.    anywhere a statement is allowed in C.
  566.  
  567.    The first thing we do is bring in some include files, as in C.  On the
  568.    NeXT, it is customary to use the "import" statement which guarantees that
  569.    the file isn't included more than once.  Using GNU CC this is not all
  570.    that nice sinds it generates a huge warning for every file being
  571.    compiled.  So, since it does not really matter, we'll stick to
  572.    `#include'.  */
  573.  
  574. #import <stdio.h>
  575. #import <objc/Object.h>
  576. #import "Queue.h"
  577. #import "Stack.h"
  578.  
  579. /* That brought in class definitions for Objects, Queues, and Stacks.  The
  580.    Object class is the basis for all other classes, which is why it gets
  581.    brought in first.  It provides basic functional behavior which is
  582.    inherited by all derived classes.  All user created classes normally have
  583.    Object somewhere in their ancestry.
  584.  
  585.    Queue and Stack are classes of our own construction, and provide FIFO and
  586.    LIFO storage capabilities, respectively.  I'm not going to go into
  587.    implementation details here.  It's irrelevant how they work, all that is
  588.    important is that they both respond to 'put:' and 'get'.  If you want to
  589.    inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  590.  
  591.    A simple Class definition follows.  It inherits directly from the base
  592.    class "Object".  This gives it lots of nice properties, not the least of
  593.    which is the ability to be referenced by any pointer of the generic
  594.    object type "id".  All objects can be pointed to by any id variable, and
  595.    the default return type from methods is id.  This allows messages to be
  596.    embedded in other messages, either as receivers or arguments.
  597.  
  598.    An Int object allocates space for a single integer.  The "report" message
  599.    causes it to report its value.  Everything between the @implementation
  600.    and the @end is part of the class definition.
  601.  
  602.    Note - It is *highly* unusual to have a class implementation in your main
  603.    program.  Since the object is fully defined before it gets used, no
  604.    interface description is required.  There is nothing illegal about doing
  605.    things this way, but it is so unusual that the compiler will produce a
  606.    warning for this class.  The Int class implementation is here solely for
  607.    expository purposes.  */
  608.  
  609. @implementation Int: Object    // Int is derived from Object
  610. {
  611.     int value;        // This is the data portion.  Like a struct.
  612. }
  613.  
  614. /* The following are the method definitions.  A `+' prefix means it is a
  615.    factory method, i.e., how to manufacture instances of the class.  The
  616.    body of the method is between braces, like a C function.
  617.  
  618.    This class doesn't define any factory methods.  It relies on the +alloc
  619.    method defined in class Object.  For examples of factory methods, look at
  620.    the +new method defined in the Stack or Queue implementations.
  621.  
  622.    Self is a special variable, which refers to the object currently being
  623.    manipulated.  Super refers to the parent class of self.  The following
  624.    method asks the parent class (Object) to hand us a new instance, which
  625.    becomes self.  Then we update the instance variables and return a pointer
  626.    to the new object.
  627.  
  628.    It is standard for methods that do not need to return any special value
  629.    to instead return self.  This allows for a nested syntax of method calls.
  630.  
  631.    The "-" in front of init means that it's an instance method, i.e.,
  632.    something a particular object should respond to.  */
  633.  
  634. -init: (int) i
  635. {
  636.   /* We're overriding the `-init' of our superclass, but we add
  637.      functionality instead of replacing it.  Therefore, first call the
  638.      `-init' of our superclass.  */
  639.   [super init];
  640.   value = i;
  641.   return self;
  642. }
  643.  
  644. -report
  645. {
  646.   printf ("%4d", value);
  647.   return self;
  648. }
  649.  
  650. @end
  651.  
  652. /* We have implemented Float and Char classes more traditionally, using
  653.    separate files for the interface (.h) and implementation (.m).  The Float
  654.    and Char objects are like the Int object, but with the obvious difference
  655.    that they work with floats and characters.  We include the interface
  656.    definitions at this point.  */
  657.  
  658. #import "Float.h"
  659. #import "Char.h"
  660.  
  661. /* If you inspect those files, note polymorphism -- methods have same
  662.    names as in the Int class.  */
  663.  
  664. int main (void)
  665. {
  666.     /* First create instances of "Stack" and "Queue" data structures.  */
  667.     id queue = [[Queue alloc] init];
  668.     id stack = [[Stack alloc] init];
  669.     int i, reply;
  670.     
  671.     fprintf (stderr, "Include the Char class in the demo? (y/n): ");
  672.  
  673.     /* Anything not matching `y.*' means no.  */
  674.     reply = getchar ();
  675.  
  676.     for (i = 5; i > -6; --i)
  677.       {
  678.     /* Depending on which version of the demo we're running, we
  679.        alternately put Ints and Floats onto the queue and stack, or
  680.        Ints, Floats, and Chars.  */
  681.     if (reply == 'y')
  682.       {
  683.         /* If I is odd we put an Int on the queue and a Char on the
  684.            stack.  If I is even we put an Char on the queue and a Float
  685.            on the stack.
  686.  
  687.            Since there is more than one method `-init:' and since
  688.            `+alloc' returns a plain, typeless, `id', the compiler
  689.            doesn't know the type of the object returned by alloc.  An
  690.            explicit cast (i.e. static type indication) ensures that the
  691.            compiler knows which `init:' is invoked---the one accepting a
  692.            char or the other one accepting an int.
  693.  
  694.            Another solution, which avoids the static type indication, is
  695.            to put typing information on the method in the method's name.
  696.            This is done for the Float class.  */
  697.         id my_char = [(Char *) [Char alloc] init: 'm' + i];
  698.  
  699.         if (i & 1)
  700.           {
  701.         [queue put: [(Int *) [Int alloc] init: i]];
  702.         [stack put: my_char];
  703.           }
  704.         else
  705.           {
  706.         [queue put: my_char];
  707.         [stack put: [[Float alloc] initFloatValue: i]];
  708.           }
  709.           }
  710.     else
  711.       {
  712.         /* If I is odd we put an Int on the queue and a Float on the
  713.            stack.  If I is even we put a Float on the queue and an Int
  714.            on the stack.  */
  715.             [queue put: ((i & 1)
  716.              ? [(Int *) [Int alloc] init: i]
  717.              : [[Float alloc] initFloatValue: i])];
  718.             [stack put: ((i & 1)
  719.              ? [[Float alloc] initFloatValue: i]
  720.              : [(Int*) [Int alloc] init: i])];
  721.     }
  722.     }
  723.  
  724.     while ([queue size] && [stack size])
  725.       {
  726.     /* The following illustrates run-time binding.  Will report be
  727.        invoked for a Float object or an Int object?  Did the user elect
  728.        for Char objects at run time?  We don't know ahead of time, but
  729.        with run-time binding and polymorphism it works properly.  The
  730.        burden is on the class implementer rather than the class user.
  731.  
  732.        Note that the following lines remain unchanged, whether we are
  733.        using the Char class or not.  The queue and stack hand us the
  734.        next object, it reports itself regardless of its type, and then
  735.        it frees itself.  */
  736.  
  737.     printf ("queue:");
  738.     [[[queue get] report] free];
  739.     printf (", stack:");
  740.     [[[stack get] report] free];
  741.     putchar('\n');
  742.       }
  743.   return 0;
  744. }
  745. @EOF
  746. set `wc -lwc <objc-sample/main.m`
  747. if test $1$2$3 != 19712617780
  748. then
  749.     echo ERROR: wc results of objc-sample/main.m are $* should be 197 1261 7780
  750. fi
  751.  
  752. chmod 644 objc-sample/main.m
  753.  
  754. if test -f objc-sample/Makefile
  755. then
  756.     echo Ok to overwrite existing file objc-sample/Makefile\?
  757.     read answer
  758.     case "$answer" in
  759.     [yY]*)    echo Proceeding;;
  760.     *)    echo Aborting; exit 1;;
  761.     esac
  762.     rm -f objc-sample/Makefile
  763.     if test -f objc-sample/Makefile
  764.     then
  765.         echo Error: could not remove objc-sample/Makefile, aborting
  766.         exit 1
  767.     fi
  768. fi
  769. echo x - objc-sample/Makefile
  770. cat >objc-sample/Makefile <<'@EOF'
  771. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  772. # runtime library with object support.  It also works on a NeXT.
  773. # Don't know about Stepstone.
  774.  
  775. .SUFFIXES: .o .m
  776. .m.o:
  777.     $(CC) -c $(CFLAGS) $<
  778.  
  779. # Use this on a NeXT
  780. #CC=        cc
  781. #LIBS=        
  782. # Use this with GNU CC on a non-NeXT,
  783. # and avoid the GCC moaning on using #import.
  784. CC=        gcc -Wno-import
  785. LIBS=        -lobjc
  786. LDFLAGS=    -L/usr/local/lib -L/usr/gnu/lib
  787.  
  788. CFLAGS=        -Wall -g
  789. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  790.  
  791. demo: $(OFILES)
  792.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  793.  
  794. clean:
  795.     rm -f $(OFILES) demo
  796.     
  797. Char.o : Char.m Char.h 
  798.  
  799. Float.o : Float.m Float.h 
  800.  
  801. Node.o : Node.m Node.h 
  802.  
  803. Queue.o : Queue.m Queue.h Node.h 
  804.  
  805. Stack.o : Stack.m Stack.h Node.h 
  806.  
  807. main.o : main.m Queue.h Node.h Stack.h Float.h
  808. @EOF
  809. set `wc -lwc <objc-sample/Makefile`
  810. if test $1$2$3 != 37127783
  811. then
  812.     echo ERROR: wc results of objc-sample/Makefile are $* should be 37 127 783
  813. fi
  814.  
  815. chmod 644 objc-sample/Makefile
  816.  
  817. if test -f objc-sample/Float.m
  818. then
  819.     echo Ok to overwrite existing file objc-sample/Float.m\?
  820.     read answer
  821.     case "$answer" in
  822.     [yY]*)    echo Proceeding;;
  823.     *)    echo Aborting; exit 1;;
  824.     esac
  825.     rm -f objc-sample/Float.m
  826.     if test -f objc-sample/Float.m
  827.     then
  828.         echo Error: could not remove objc-sample/Float.m, aborting
  829.         exit 1
  830.     fi
  831. fi
  832. echo x - objc-sample/Float.m
  833. cat >objc-sample/Float.m <<'@EOF'
  834. #import <stdio.h>
  835. #import "Float.h"
  836.  
  837. @implementation Float
  838. {
  839.   float value;
  840. }
  841.  
  842. -initFloatValue: (float) x
  843. {
  844.   [super init];
  845.   value = x;
  846.   return self;
  847. }
  848.  
  849. -report
  850. {
  851.   printf ("%4.1f", value);
  852.   return self;
  853. }
  854.  
  855. @end
  856. @EOF
  857. set `wc -lwc <objc-sample/Float.m`
  858. if test $1$2$3 != 2231215
  859. then
  860.     echo ERROR: wc results of objc-sample/Float.m are $* should be 22 31 215
  861. fi
  862.  
  863. chmod 644 objc-sample/Float.m
  864.  
  865. if test -f objc-sample/COPYRIGHT
  866. then
  867.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  868.     read answer
  869.     case "$answer" in
  870.     [yY]*)    echo Proceeding;;
  871.     *)    echo Aborting; exit 1;;
  872.     esac
  873.     rm -f objc-sample/COPYRIGHT
  874.     if test -f objc-sample/COPYRIGHT
  875.     then
  876.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  877.         exit 1
  878.     fi
  879. fi
  880. echo x - objc-sample/COPYRIGHT
  881. cat >objc-sample/COPYRIGHT <<'@EOF'
  882. This copyright notice applies to all source files distributed in the
  883. comp.lang.objective-c FAQ: `A Simple Sample Objective-C program'.
  884.  
  885. Copyright (C) 1993 Paul J. Sanchez and Bill Shirley
  886. Copyright (C) 1994 Pieter J. Schoenmakers
  887.  
  888. The `simple sample Objective-C program' is free software; you can
  889. redistribute it and/or modify it under the terms of the GNU General Public
  890. License as published by the Free Software Foundation; either version 2, or
  891. (at your option) any later version.
  892.  
  893. The `simple sample Objective-C program' is distributed in the hope that it
  894. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  895. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  896. Public License for more details.
  897.  
  898. You should have received a copy of the GNU General Public License
  899. along with GNU Emacs; see the file COPYING.  If not, write to
  900. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  901. @EOF
  902. set `wc -lwc <objc-sample/COPYRIGHT`
  903. if test $1$2$3 != 19150944
  904. then
  905.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 19 150 944
  906. fi
  907.  
  908. chmod 644 objc-sample/COPYRIGHT
  909.  
  910. if test -f objc-sample/Float.h
  911. then
  912.     echo Ok to overwrite existing file objc-sample/Float.h\?
  913.     read answer
  914.     case "$answer" in
  915.     [yY]*)    echo Proceeding;;
  916.     *)    echo Aborting; exit 1;;
  917.     esac
  918.     rm -f objc-sample/Float.h
  919.     if test -f objc-sample/Float.h
  920.     then
  921.         echo Error: could not remove objc-sample/Float.h, aborting
  922.         exit 1
  923.     fi
  924. fi
  925. echo x - objc-sample/Float.h
  926. cat >objc-sample/Float.h <<'@EOF'
  927. #import <objc/Object.h>
  928.  
  929. @interface Float: Object
  930. {
  931.   float value;
  932. }
  933.  
  934. -initFloatValue: (float) x;
  935. -report;
  936.  
  937. @end
  938. @EOF
  939. set `wc -lwc <objc-sample/Float.h`
  940. if test $1$2$3 != 1114113
  941. then
  942.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 14 113
  943. fi
  944.  
  945. chmod 644 objc-sample/Float.h
  946.  
  947. chmod 755 objc-sample
  948.  
  949. exit 0
  950.  
  951.